<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webgl渲染到纹理</title>

    <script src="lib/webgl-debug.js"></script>
    <script src="lib/webgl-utils.js"></script>
    <script src="lib/cuon-utils.js"></script>
    <script src="lib/cuon-matrix.js"></script>
</head>

<body onload="main()">
    <canvas width="800" height="800" id="canvas"></canvas>
</body>

<script>
    var vs = `
    attribute vec4 position;
    void main(){
        gl_Position = position;
    }
    `
    var fs = `
    void main(){
        gl_FragColor = vec4(1,0,0,1);
    }
    `
    var OFFSCREEN_WIDTH = 256;
    var OFFSCREEN_HEIGHT = 256;


    var mvs = `
        attribute vec4 position ;
        void main(){
            gl_Position = position;
        }
    `
    var mfs = `
    #ifdef GL_ES
    precision mediump float;
    #endif
    uniform sampler2D sampler;
    void main(){
        gl_FragColor = texture2D(sampler,vec2(0.5,0.5));
    }
    `

    function main() {
        var canvas = document.getElementById("canvas");
        gl = getWebGLContext(canvas);
        // 初始化着色器
        var initProgram = initShaders(gl, vs, fs);
        if (!initProgram) {
            console.log("初始化着色器失败");
            return;
        }
        //初始化 fbo
        var fbo = initFrameBufferObject(gl);
        //初始化顶点数据
        var n = initVertexBuffers(gl);

        //绑定帧缓冲区
        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
        gl.viewport(0, 0, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
        //设置背景色
        gl.clearColor(0, 0, 0, 1);
        //清空颜色缓冲区和深度缓冲区
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        if (n < 0) {
            return;
        }

        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);

        gl.viewport(0, 0, canvas.width, canvas.height);
        var newProgram = initShaders(gl, mvs, mfs);
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
        var n = initVertexBuffers(gl);
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);


    }

    // 初始化帧缓冲区对象
    function initFrameBufferObject(gl) {
        var framebuffer, texture, depthbuffer;

        //创建fbo 帧缓冲区
        framebuffer = gl.createFramebuffer();
        //创建纹理对象,并设置其大小和参数
        texture = gl.createTexture();
        // 绑定纹理对象
        gl.bindTexture(gl.TEXTURE_2D, texture);
        // 将纹理图像分配给纹理对象，
        //参数：纹理类型，未知？，图像的内部格式，图像宽度，图像高度，纹理的数据格式（必须要跟图像的内部格式一样），纹理的数据类型，纹理图像
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        // 设置纹理参数
        //参数：纹理类型，纹理参数，纹理值
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        //储存纹理对象
        framebuffer.texture = texture;

        //将帧缓冲区绑定到程序上
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
        //将framebuffer渲染到一个纹理附件中
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);

        //创建深度缓冲区
        depthbuffer = gl.createRenderbuffer();
        // 绑定深度缓冲区
        gl.bindRenderbuffer(gl.RENDERBUFFER, depthbuffer);
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
        //将帧缓冲区绑定到渲染缓冲区上
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthbuffer)
            //解除帧缓冲区绑定
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        // 解除纹理
        gl.bindTexture(gl.TEXTURE_2D, null);
        //解除 渲染缓冲区
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        return framebuffer;
    }

    function initVertexBuffers(gl) {
        var vertexDatas = new Float32Array([-0.5, 0.5, -0.5, -0.5,
            0.5, 0.5,
            0.5, -0.5
        ])

        var n = 4;

        var vertexBuffer = gl.createBuffer();
        if (!vertexBuffer) {
            console.log("创建缓冲区失败")
            return -1;
        }

        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, vertexDatas, gl.STATIC_DRAW);
        var position = gl.getAttribLocation(gl.program, "position");
        gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(position);
        return n;
    }
</script>

</html>